﻿using System;
using System.IO;

namespace UtilsExtensionsAndHelpers.Helpers.Implimentations
{
    public class FileHelper : IFileHelper
    {
        private Action<String> _feedbackProvider;
        /// <summary>
        /// Get or set the action that provides feedback. 
        /// A message (string) will be passed in.
        /// IE. Log(message), Console.WriteLine(message)
        /// </summary>
        public Action<String> FeedbackProvider
        {
            get { return _feedbackProvider ?? Console.WriteLine; }
            set { _feedbackProvider = value; }
        }

        /// <summary>
        /// Creates the needed parent directories if they don't exist.
        /// </summary>
        /// <param name="fileName">Name to the file you want the parent directory path created for.</param>
        public void EnsureParentDirExists(string fileName)
        {
            var file = new FileInfo(fileName);
            try
            {
                if (!file.Directory.Exists) Directory.CreateDirectory(file.DirectoryName);
            }
            catch (Exception e)
            {
                FeedbackProvider(e.Message);
            }
        }

        /// <summary>
        /// Reads through a file line by line till it hits an ending marker, then passes what it's found to the action.
        /// After passing a string to the action, it clears and starts again. Very handy for xml lists. Just set the ending
        /// tag as the endingMarker.
        /// </summary>
        /// <param name="filePath">Full path to the file being read.</param>
        /// <param name="beingLinesToSkip">If you need to skip any lines, like DTD</param>
        /// <param name="endingMarker">A string marking the end of a section</param>
        /// <param name="action">What you want to do with the string</param>
        public void ReadThroghFile(string filePath, string endingMarker, Action<string> action)
        {
            ReadThroghFile(filePath, 0, endingMarker, action, FeedbackProvider);
        }
        /// <summary>
        /// Reads through a file line by line till it hits an ending marker, then passes what it's found to the action.
        /// After passing a string to the action, it clears and starts again. Very handy for xml lists. Just set the ending
        /// tag as the endingMarker.
        /// </summary>
        /// <param name="filePath">Full path to the file being read.</param>
        /// <param name="beingLinesToSkip">If you need to skip any lines, like DTD</param>
        /// <param name="endingMarker">A string marking the end of a section</param>
        /// <param name="action">What you want to do with the string</param>
        public void ReadThroghFile(string filePath, int beingLinesToSkip, string endingMarker, Action<string> action)
        {
            ReadThroghFile(filePath, beingLinesToSkip, endingMarker, action, FeedbackProvider);
        }
        /// <summary>
        /// Reads through a file line by line till it hits an ending marker, then passes what it's found to the action.
        /// After passing a string to the action, it clears and starts again. Very handy for xml lists. Just set the ending
        /// tag as the endingMarker.
        /// </summary>
        /// <param name="filePath">Full path to the file being read.</param>
        /// <param name="beingLinesToSkip">If you need to skip any lines, like DTD</param>
        /// <param name="endingMarker">A string marking the end of a section</param>
        /// <param name="action">What you want to do with the string</param>
        /// <param name="feedbackProvider">A method to handle messages</param>
        public void ReadThroghFile(string filePath, int beingLinesToSkip, string endingMarker, Action<string> action, Action<string> feedbackProvider)
        {
            using (var feed = new StreamReader(filePath))
            {
                feedbackProvider("Reading through: " + filePath);

                var currentLine = String.Empty;
                var runningString = String.Empty;

                for (var i = 0; i < beingLinesToSkip; i++) feed.ReadLine(); //get past the feed header

                while ((currentLine = feed.ReadLine()) != null)
                {
                    runningString += currentLine;
                    if (!currentLine.Contains(endingMarker)) continue;

                    action(runningString);
                    runningString = String.Empty;
                }
            }
        }

        /// <summary>
        /// Reads through a file line by line, passing each line to the action.
        /// Very handy for CSV for any other text files. 
        /// </summary>
        /// <param name="filePath">Full path to the file being read.</param>
        /// <param name="action">What you want to do with the string</param>
        public void ReadThroghFileByLine(string filePath, Action<string> action)
        {
            ReadThroghFileByLine(filePath, 0, action, FeedbackProvider);
        }
        /// <summary>
        /// Reads through a file line by line, passing each line to the action.
        /// Very handy for CSV for any other text files. 
        /// </summary>
        /// <param name="filePath">Full path to the file being read.</param>
        /// <param name="beingLinesToSkip">If you need to skip any lines, like CSV hearers</param>
        /// <param name="action">What you want to do with the string</param>
        public void ReadThroghFileByLine(string filePath, int beingLinesToSkip, Action<string> action)
        {
            ReadThroghFileByLine(filePath, beingLinesToSkip, action, FeedbackProvider);
        }
        /// <summary>
        /// Reads through a file line by line, passing each line to the action.
        /// Very handy for CSV for any other text files. 
        /// </summary>
        /// <param name="filePath">Full path to the file being read.</param>
        /// <param name="beingLinesToSkip">If you need to skip any lines, like CSV hearers</param>
        /// <param name="action">What you want to do with the string</param>
        /// <param name="feedbackProvider">A method to handle messages</param>
        public void ReadThroghFileByLine(string filePath, int beingLinesToSkip, Action<string> action, Action<string> feedbackProvider)
        {
            using (var feed = new StreamReader(filePath))
            {
                feedbackProvider("Reading through: " + filePath);

                var currentLine = String.Empty;

                for (var i = 0; i < beingLinesToSkip; i++) feed.ReadLine(); //get past the feed header

                while ((currentLine = feed.ReadLine()) != null)
                {
                    action(currentLine);
                }
            }
        }
    }
}
